<?php
class Base_dao extends CI_Model
{	
	// Cada clase hija debe definir los valores de estos atributos ya que los métodos se basan en estos valores
	private $nombreTabla = 'tableName';
	private $nombreColumnaID = 'id';
	private $nombreModelo = 'model';

	// Constructor y Métodos
	function __construct()
    {
		parent::__construct();
	}
	
	/**
	 * Inserta o actualiza los datos del objeto actual en la tabla asociada.
	 *
	 * Devuelve un arreglo de tres elementos con el resultado de la operación:
	 *	** 'exito' 		=> booleano que indica si la operación fue realizada exitosamente.
	 *	** 'error_msg' 	=> si hubiera ocurrido un error, se guarda la información asociada en este elemento.
	 *	** 'idGenerado' => si se hubiera tratado de una inserción, se guarda en este elemento, el id generado.
	 *
	 * @param	string	Nombre de la tabla donde se insertarán los datos
	 * @param	string	Nombre de la columna en la tabla referida al ID
	 * @param	object	Objeto a insertarse/editarse. Del tipo de la clase hija de la clase actual (DTO)
	 * @param	long	Código ID a modificar (o 0 si es nuevo)
	 */
	public function guardar($tabla, $columnaID, $objeto, $idObjeto)
	{
		$result = array();
		
		if($idObjeto == 0) // Se debe insertar un nuevo registro en la tabla
		{
			$result['exito'] = $this->db->insert("$tabla", $objeto);
			if($result['exito']) $result['idGenerado'] = $this->db->insert_id();
		}
		else
		{	
			$this->db->where("$columnaID", $idObjeto);
			$result['exito'] = $this->db->update("$tabla", $objeto);
		}
		
		$error = $this->db->_error_message();
		if($error != '') $result['error_msg'] = $this->db->_error_number() . '/' . $error;
		else $result['error_msg'] = '';
		return $result;
	}
	
	
	/**
	 * Elimina un registro según el id actual del objeto, de la tabla asociada.
	 *
	 * Devuelve un arreglo de dos elementos con el resultado de la operación:
	 *	** 'exito' 		=> booleano que indica si la operación fue realizada exitosamente.
	 *	** 'error_msg' 	=> si hubiera ocurrido un error, se guarda la información asociada en este elemento.
	 *
	 * @param	string	Nombre de la tabla donde se eliminarán los datos
	 * @param	string	Nombre de la columna en la tabla referida al ID
	 * @param	long	Código ID a borrar
	 */
	public function borrar($tabla, $columnaID, $idBorrar)
	{
		$result = array();
		
		$result['exito'] = $this->db->delete("$tabla", array("$columnaID" => $idBorrar));
		$result['error_msg'] = $this->db->_error_message();
		
		return $result;
	}
	
	
	/**
	 * Devuelve un objeto del tipo de la clase que invocó la operación, cuyo ID coincida con el pasado como parámetro
	 * ($idBuscado). Si no se encontrase coincidencia, devuelve NULL.
	 *
	 * @param	string	Nombre de la tabla donde se buscarán los datos
	 * @param	string	Nombre de la columna en la tabla referida al ID
	 * @param	string	Nombre del modelo DTO que se quiere obtener	 
	 * @param	long	Código ID buscado
	 */
	public function obtenerObjetoPorID($tabla, $columnaID, $modelo, $idBuscado)
	{
		$elemento = NULL;
		
		if ($idBuscado != 0)
		{	
			$resultado = $this->db->get_where("$tabla", array("$columnaID" => $idBuscado));
			if ($resultado->num_rows() > 0)
			{
				$elemento = $resultado->row(0, "$modelo");
			}
		}
		
		return $elemento;
	}
	
	
	/**
	 * Obtiene los registros de la tabla asociada a la clase actual. Puede devolver un conjunto de objetos,
	 * en base a los resultados, o directamente los resultados de la consulta.
	 *
	 * @param	string		Nombre de la tabla donde se buscarán los datos
	 * @param	string		Nombre del modelo DTO que se quiere obtener	 	 
	 * @param	array(string campo => string valor)	Opcional. Condiciones para filtrar la búsqueda
	 * @param	bool		Opcional. True para devolver objetos, False para devolver el resultado de la consulta
	 * @param	int			Opcional. Cantidad límite de resultados
	 * @param	string		Opcional. Campos a seleccionarse. Por defecto, * (todos).	 
	 */	
	public function obtenerDatos($tabla, $modelo, $condiciones = array(), $crearObjetos = false, $limite = 0, $camposSelect = '')
	{
		$arreglo = array();
		
		if ($camposSelect != '') $this->db->select("$camposSelect");
		if ($limite > 0) $this->db->limit($limite);
		
		if (sizeof($condiciones) > 0) {
			foreach($condiciones as $key => $value) {
				$this->db->where($key, $value);
			}
		}
		
		$consulta = $this->db->get("$tabla");	
		if ($consulta->num_rows() > 0)
		{
			$indice = 0;
			if ($crearObjetos)
			{
				foreach ($consulta->result("$modelo") as $row)
				{
					$arreglo[$indice] = $row;
					$indice++;
				}
			}
			else
			{
				foreach ($consulta->result() as $row)
				{
					$arreglo[$indice] = $row;
					$indice++;
				}
			}
			
		}
		return $arreglo;
	}
}